import pandas as pd
import numpy as np
import re
from datetime import datetime
import logging

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    filename='data_cleaning.log'
)


def clean_price(price_str):
    """清洗价格数据"""
    try:
        # 去除¥符号和多余空格
        price = price_str.replace('¥', '').strip()
        # 处理价格范围（如"12.00-15.00"取平均值）
        if '-' in price:
            prices = [float(p) for p in price.split('-')]
            return round(sum(prices) / len(prices), 2)
        return float(price)
    except:
        return np.nan


def clean_comment_count(comment_str):
    """清洗评论数量数据"""
    try:
        # 提取数字部分
        comment = re.sub(r'[^\d]', '', comment_str)
        return int(comment) if comment else 0
    except:
        return 0


def clean_pub_date(date_str):
    """清洗出版日期数据"""
    try:
        # 处理多种日期格式
        date_str = date_str.strip()

        # 匹配"2023年1月"格式
        if re.match(r'\d{4}年\d{1,2}月', date_str):
            return datetime.strptime(date_str, '%Y年%m月').strftime('%Y-%m')

        # 匹配"2023-01"格式
        elif re.match(r'\d{4}-\d{1,2}', date_str):
            return datetime.strptime(date_str, '%Y-%m').strftime('%Y-%m')

        # 匹配"2023年1月第1版"格式
        elif re.match(r'\d{4}年\d{1,2}月', date_str.split('第')[0]):
            return datetime.strptime(date_str.split('第')[0], '%Y年%m月').strftime('%Y-%m')

        # 其他格式返回原始值
        else:
            return date_str
    except:
        return date_str


def clean_author(author_str):
    """清洗作者数据"""
    try:
        # 去除多余空格和特殊符号
        author = re.sub(r'[\\/|；，、]', ',', author_str.strip())
        # 处理多位作者情况
        authors = [a.strip() for a in author.split(',') if a.strip()]
        return ', '.join(authors) if authors else '未知'
    except:
        return '未知'


def clean_publisher(publisher_str):
    """清洗出版社数据"""
    try:
        # 去除出版社后的冗余信息
        publisher = publisher_str.split('出版社')[0].strip()
        return publisher if publisher else '未知'
    except:
        return '未知'


def clean_title(title_str):
    """清洗书名数据"""
    try:
        # 去除书名中的广告语和特殊符号
        title = re.sub(r'【.*?】|\(.*?\)|（.*?）|\[.*?\]', '', title_str)
        title = re.sub(r'[【】()（）\[\]]', '', title)
        return title.strip()
    except:
        return title_str


def add_category(title):
    """根据书名添加分类标签"""
    keywords = {
        'Python': ['Python', 'python', '蟒蛇'],
        'Java': ['Java', 'java'],
        '机器学习': ['机器学习', 'ML', '深度学习', '神经网络', 'AI'],
        '数据库': ['数据库', 'SQL', 'MySQL', 'Oracle', 'MongoDB'],
        '算法': ['算法', '数据结构', 'LeetCode']
    }

    for category, words in keywords.items():
        for word in words:
            if word.lower() in title.lower():
                return category
    return '其他'


def clean_data(input_file, output_file):
    """主清洗函数"""
    try:
        # 读取原始数据
        logging.info(f"开始读取数据文件: {input_file}")
        df = pd.read_csv(input_file, encoding='utf-8-sig')

        # 数据基本情况
        logging.info(f"原始数据量: {len(df)}条")
        logging.info(f"原始字段: {df.columns.tolist()}")

        # 1. 去重处理
        df.drop_duplicates(subset=['商品链接'], keep='first', inplace=True)
        logging.info(f"去重后数据量: {len(df)}条")

        # 2. 字段清洗
        df['价格'] = df['价格'].astype(str).apply(clean_price)
        df['评论数'] = df['评论数'].astype(str).apply(clean_comment_count)
        df['出版日期'] = df['出版日期'].astype(str).apply(clean_pub_date)
        df['作者'] = df['作者'].astype(str).apply(clean_author)
        df['出版社'] = df['出版社'].astype(str).apply(clean_publisher)
        df['书名'] = df['书名'].astype(str).apply(clean_title)

        # 3. 添加新字段
        df['分类'] = df['书名'].apply(add_category)
        df['出版年份'] = df['出版日期'].str.extract(r'(\d{4})')[0]

        # 4. 处理缺失值
        df['价格'].fillna(df['价格'].median(), inplace=True)
        df['出版社'].replace('无', '未知', inplace=True)
        df['作者'].replace('无', '未知', inplace=True)

        # 5. 数据类型转换
        df['评论数'] = df['评论数'].astype(int)
        df['价格'] = df['价格'].astype(float)

        # 6. 异常值处理
        df = df[(df['价格'] > 0) & (df['价格'] < 1000)]  # 去除异常价格
        df = df[df['评论数'] >= 0]  # 去除负评论数

        # 7. 保存清洗后数据
        df.to_csv(output_file, index=False, encoding='utf-8-sig')
        logging.info(f"数据清洗完成，保存到: {output_file}")
        logging.info(f"最终数据量: {len(df)}条")

        # 返回清洗后的DataFrame
        return df

    except Exception as e:
        logging.error(f"数据清洗过程中出错: {e}")
        raise


if __name__ == '__main__':
    # 配置输入输出文件
    input_csv = 'dangdang_data.csv'  # 原始数据文件
    output_csv = 'dangdang_cleaned_data.csv'  # 清洗后数据文件

    # 执行清洗
    cleaned_data = clean_data(input_csv, output_csv)

    # 打印清洗后的数据样例
    print("\n清洗后的数据样例：")
    print(cleaned_data.head())

    # 打印基本统计信息
    print("\n基本统计信息：")
    print(cleaned_data.describe())

    # 打印分类统计
    print("\n图书分类统计：")
    print(cleaned_data['分类'].value_counts())